int An integer capable of storing signed whole numbers real A real value string A sequence of ascii characters char An ascii characterA variable can be declared using these types through a simple declaration either at the start of your program (visible to the entire program) or at the start of a function (only visible to that function). A typical declaration is of the form:
int sharenumber;You can build on these basic types in two ways, arrays allow you to design storage areas that contain a sequence of data values of a particular type and structures allow you to combine multiple types within a larger container.
An array is declared through the use of the typedef
statement.
If you are used to the C language then, you should be aware that you must
use typedef
to produce arrays.
typedef real pricetype[100] pricetype prices;In the example above a new type called
pricetype
is
created. This new
type consists of 100 reals. The program then defines the variable
prices
to be of the pricetype
type. When you
define an array in this manner, you can index each element within the
array using [x]
, where x is the member of interest. All
references start at 0.
A structure is produced with the struct
statement. This
allows any number of data types to be grouped together.
struct group { string securityname; real price; };This defines a structure named
group
that has fields called
securityname
(a string) and price
(a
real). Having defined a structure you may declare a variable
newvar
that is of this type with:
struct group newvar;You can can also combine the definition of the structure with the declaration of the variable:
struct group { string securityname; real price; } newvar;It is also possible to use typedef with structures, for example to create a new type
groupt
that is an alias
for the group
structure you would use:
typedef struct group groupt
To reference fields within a structure simply use the .
operator:
newvar.securityname="security name not set"; newvar.price=0.0;
You may store a date using the DATE
type. The date type
is set to a specific date with
dialogdaterange and
getdate commands. Most operators are defined
on the date type and you can add a whole number of days to a date
by simply adding an integer (the number of days) to the date in question.
Securities are stored using the SECURITY
type. Typically
this is set by calling the
dialogsecurity function that prompts the
user for a valid security name. Few operators are valid on the
SECURITY
type.
{ statement1; statement2; }
An expression in the macro language can include an assignment. For example the expression:
b=(a=10)+1Will assign a to 10, b to 11 and has a value of 11.
A complete set of operators, with full precedence, is supported. The normal mathematical operations are available using the conventional symbols:
* Multiplication / Division + Addition - Subtraction
For comparisons the operators are:
!= Not equal = Equal < Less than > Greater than <= Less than or equal to >= Greater than or equal to
Other operators are:
^ Exclusive or & bitwise and | bitwise or && logical and || logical or (expr) ParenthesisYou should note that not all types will support all operators.
Constants can be included within expressions. The available constants include integers, real numbers and strings enclosed within quotes.
A function allows you to group a number of statements together so that you may reuse the same code in multiple ways. A function is declared using the syntax:
typename function_name(arguments) { variable_declarations statements }The
typename
declaration specifies the type that will
be returned by the function and can be omitted if the function
returns no values.
In the simplest form, the arguments used by a function are declared in the same way as normal variables but using a comma to delimit each argument. For example, if a function requires two arguments, the first being an integer and the second a string the declaration would be:
function_name(int num,string text) { ...... ...... }This creates two variables for use by the function. The first
num
is
the integer and the second, text
, is the
string. So if the function
was called with:
function_name(10,"hello");Then
num
would be 10 and
text
would be "hello". Note with this syntax
the variables are strictly local so you CANNOT assign new values to them
and have the caller see those new values. The assignment will only
apply while the program is executing within the context of the function.
Frequently you may wish to return multiple values from the function and
therefore need to assign values that can be seen outside of the scope
of the function. This can be achieved with the byref
qualifier.
function_name(byref int num,byref string text) { num=100; }When arguments are declared in this manner, the function is able to modify the actual values passed by the caller:
a=200; function_name(a,"hello"); print(a);In this instance the value that will be displayed will be 100 and NOT 200. If the
byref
keyword had not been included,
the value 200 would have been shown.
When you wish to pass structures to a function, either by value or by reference, you will need to declare the argument that is a structure using a real type and not with the struct keyword. For example:
struct simplestruct { ..... }; typedef simplestruct structtype; function(byref structtype arg) { .... ..... }This same method should also be employed when you wish to pass arrays to functions.
Functions can return values using the return
command.
The type that
is to be returned should be specified in front of the function name. For
example if the macro has a function called createname
that
returns a string the function would be written:
string createname()
{
....
....
}
At any point within the function, a call can be made to return
command passing a value that evaluates to a string. If you need to be
able to return, prior to the last statement in a function, from a function
that has no return value then you can simply use return
without an argument.
The macro language provides a complete if..then..else construct:
if (expression) statement else statementThe else part of the construct is entirely optional and can be omitted when not necessary. At execution time, the expression within the if statement is evaluated. When it is non-zero (TRUE), the first statement will be executed. If it is zero and an else clause is specified, the second statement following the else will be executed. Although the expression in the if statement is treated as having boolean properties, it can be of any integer type.
The while construct provides the basic building block for iteration within macros. The while construct allows a statement (including a compound statement) to be continually executed:
while (condition) { ..... code ..... ..... }The statements within the braces will be executed until the boolean expression given by condition becomes FALSE. With most macros it is usually that the code that is executed within the loop will eventually result in the condition becoming FALSE. If the condition is FALSE before the loop starts then the loop will not be executed. If the loop should always be executed at least once, then the do..while construct should be used:
do { ..... code ..... ..... } while (condition);The loop is executed once and the condition is evaluated. If it is FALSE the loop will be executed from the top, otherwise the statement following the while() command will be executed.
Within a while (or do...while) loop, the continue
and
break
commands may be used. The continue
statement takes the point of execution back to the top of the loop.
The break
command will change the point of execution to the first statement
that follows the loop.
The for construct is based upon the while construct. The statement
for( i=0; i<100; i=i+1) print(i,"\n");Is equivalent to the statement:
i=0; while (i<100) { print(i,"\n"); i=i+1; }Unlike C or C++ you must specify all three expressions within the for statement.
The constant PI.
The NOPRICE constant gives a real number that indicates that no valid price was available. These are used by the price database and by the graph plotting functions to indicate no information and in the case of graph plotting, that interpolation/extrapolation is required.
Returns the arc cosine of x in the range of 0 to PI. x should be in the range of -1 to 1.
Returns the arc sine of x in the range of -PI/2 to PI/2 radians. x should be in range of -1 to 1.
Returns the arc tangent of x in the range -PI/2 to PI/2 radians.
The cos function returns the cosine of its argument x measured in radians.
The sin function returns the sine of its argument x measured in radians.
Returns the tangent of x measured in radians.
Returns the hyperbolic cosine of x.
Returns the hyperbolic sine of x.
Returns the hyperbolic tangent of x.
Returns e^x.
Returns the natural logarithm of x. Argument x must be positive.
Returns the logarithm base ten of x. Argument x must be positive.
Returns the square root of x. Argument x must be positive.
Returns the smallest integer not less than x.
Returns the absolute value of x.
Returns the largest integer not greater than x.
Returns x^y.
Returns the real remainder of the division of x by y.
Returns the arc tangent of y/x in the range of -PI to PI.
windowopen(name,refreshfnc,menu) string name; string refreshfnc; MENU menu;
Opens a window with the title specified by name. The function will return a value of type WINDOW and this value should be used in future window based functions when this window is to be referenced. The argument refreshfnc names the function that will be executed when the window is resized and menu specifies the menus that should be attached to the window.
Closes the window specified by window.
windowclose(window) WINDOW window;
Clears the window specified by window.
clearpage(window) WINDOW window;
Ensures the window specified by window is up to date.
drawpage(window) WINDOW window;
Draws a line from the current position in window to the coordinate x,y.
drawto(window,x,y) WINDOW window; real x,y;
Moves the current position in window to the coordinate x,y.
moveto(window,x,y) WINDOW window; real x,y;
Sets width and height to the current width and height of the window window.
size(window,width,height) WINDOW window; real width,height;
Draws a complete axis in the window window. On the X axis dates will range from date1 to date2 and on the Y axis values will go from min_y to max_y.
axis_date(window,date1,date2,min_y,max_y) WINDOW window; DATE date1,date2; real min_y,max_y;
Plots the data given by data in window using information previously set by axis_date. The maxsize argument should specify how many numbers are stored in data. The start and end arguments give the range of indices within data that should be plotted.
plot(window,data,maxsize, start, end) WINDOW window; typedef real realarray[x] realarray data; int maxsize; int start,end;
Note that the information in data may be sparse. If a value is not known and extrapolation is required then the value in question should be set to the constant NOPRICE
Sets the line width for window.
linewidth(window,width) WINDOW window; real width;
Sets the current colour for window.
colour(window,colour)color(window,colour) WINDOW window; string colour,color;
menuopen(menu) MENU menu;Opens the specified menu. The menu can then be built and passed to a windowopen() call:
WINDOW win;
MENU mymenu;
....
....
menuopen(mymenu);
menu(mymenu,"Project","Exit","window_exit");
menu(mymenu,"Project","Select security","selectsecurity");
win=windowopen("Prices of a security","window_refresh",mymenu);
Closes the specified menu.
menuclose(menu) MENU menu;
Adds the menu bar and item to the specified menu that should already have been opened with menuopen. The menu item itemname should appear in the bar barname. The function named functionname will be called when the menu item is selected by the user.
menu(menu,barname,itemname,functionname) MENU menu; string barname; string itemname; string functionname
fileopen(name,access) string name; string access;
Opens the file specified by name with the access permissions specified by the access string. The access permissions are convential stdio values:
r reading w create for writing (or truncate if file already exists) a append at end of file r+ open for reading and writing w+ truncate or create for update a+ open (append) or create for update
The returned value from fileopen is of type FILE and should be assigned to a variable of FILE type. The file can be read or written as appropriate. However before the file is accessed it is recommended you use eof() to determine that the file is correctly open. A typical code fragment for reading from a file would be:
FILE file;
string input;
....
....
file=fileopen("pricedump","r");
if ( eof(file)== 2) {
print("Could not open file");
return;
}
.....
while (eof(file)==0) {
filereadline(file,input);
print(input,"\n");
}
fileclose(file);
fileclose(file) FILE file;
Closes a previously opened file. A file for which eof() returns 2 does not need to be closed with this function.
fileprint(file,arg1,...,argn) FILE file; (any) argi;
Writes the arguments arg1 to argn to the specified file in ascii format. The arguments can be of any type, provided they have an ascii representation. Those that types that are appropriate include:
Writes the arguments arg1 to argn to the specified file in binary format. Although all types can be written using this function, the output file may not be transferable or readily readable.
filewrite(file,arg1,...,argn) FILE file; (any) argi;
Reads the arguments arg1 to argn from the file. The arguments can be of any type. Typically to read ascii files you will need to use the filereadline() command that is able to interpret files on a line by line basis.
fileread(file,arg1,..,argn) FILE file; (any) argi;
Reads the arguments arg1 to argn from the file. The arguments must be of type string. Each line in the file will be read into the relevant argument.
filereadline(file,arg1,..,argn) FILE file; string argi;
eof(file) FILE file;
Returns the state of the file:
file=fileopen("pricedump","r");
if ( eof(file)== 2) {
print("Could not open file");
return;
}
while (eof(file)==0) {
filereadline(file,input);
print(input,"\n");
}
fileclose(file);
mainmenu(barname,itemname,funcname) string barname; string itemname; string funcname;
Attaches a new menu item to a bar on the main window. For example to
create a new menu option for the 'Project' menu one would use:
mainmenu("Project","Write prices to file","dump_prices");
This will result in the function dump_prices being called whenever the
'Write prices to file' menu item is selected.
dialogsecurity(title) string title;
Allows the user to select a security from all the securities that are
known to the system. This returns a value of type SECURITY.
SECURITY security;
....
....
security=dialogsecurity("Enter a security");
int dialogyesno(message,okmsg,cancelmsg) string message; string okmsg; string cancelmsg;
Displays a yes/no dialog with the message specified. The "OK" button
will be labeled with the string specified by okmsg
and the "CANCEL" button will be labeled by cancelmsg
.
The function returns 1 if the user selects "OK", otherwise 0 will
be returned.
dialogmessage(message) string message;
Displays a dialog with the message specified.
int dialogstring(windowtitle, message, stringedit,length) string windowtitle; string message; string stringedit; int length;
Displays a dialog where the user can edit the string given by
stringedit
. The maximum length of the string is given
by length
. The dialog will be in a window with the
title given by windowtitle
and the string edit area
will be labeled with message
.
int dialogdaterange(title,startdate,enddate) string title; DATE startdate; DATE enddate;
Allows the user to select a range of dates starting with the
date specified by startdate
and finishing
with enddate
. If the user hits the "OK" button
then the function returns 1, else the function returns 0
indicating the user canceled the operation. When 1 is returned
the startdate
and enddate
arguments will
be set to the new date range.
Converts a date in ascii form to a date (in the first form) or sets a date to today (in the second form).
getdate(date,stringdate)getdate(date) DATE date; string stringdate;
Converts a date to the number of days elapsed since 1st Jan 1970.
int date2days(date) DATE date;
getprices(security,data,date,num)SECURITY security; typedef real realarray[x]; realarray data; DATE date; int num;
Fetches the prices for the specified security. The array given by data should be large enough to store all the prices for the given security. The date that data[0] represents will be returned in date and the total number of prices in the array will be returned in num.
Returns TRUE if the value given by price represents a valid price. Not all real numbers are prices so as to allow information to be held in the price database indicating that no price exists for a given date. See the constant NOPRICE
int isaprice(price) real price;
Executes a shell with the commands given in cmdstring. The return value will be 0 if the command executed correctly, otherwise it will be -1 if a process could not be forked or -127 if the commands could not otherwise be executed.
int system(cmdstring) string cmdstring;